package dominio;

import java.io.Serializable;
import java.util.ArrayList;

import org.uqbar.commons.model.ObservableUtils;
import org.uqbar.commons.utils.Observable;

import exceptions.JardinZenLleno;

@Observable
public class JardinZen implements Serializable{

	private int sizeTerrestre = 20;
	private int sizeAcuatico = 20;
	
	private ArrayList<Planta> jardinAcuatico = new ArrayList<Planta>();
	private ArrayList<Planta> jardinTerrestre = new ArrayList<Planta>();
	
	private Planta plantinAMejorar;

	public JardinZen(){
		
	}
	
	public JardinZen(int sizeAc, int sizeTer) {
		this.sizeAcuatico = sizeAc;
		this.sizeTerrestre = sizeTer;
	}

	/**
	 * Pregunto a la planta que tipo es y resuelvo a que zona agregarlo.
	 * 
	 * @param Planta
	 */
	public void agregarPlanta(Planta p, boolean forceFire) {
		
		if (p.getTerrestre()) {
			agregarPlantaAJardin(p,this.jardinTerrestre,this.sizeTerrestre);
			if(forceFire){
				//ObservableUtils.forceFirePropertyChanged(this, "espaciosLibresTerrestre", this.getEspaciosLibresTerrestre());
			}
			
		} else {
			agregarPlantaAJardin(p,this.jardinAcuatico,this.sizeAcuatico);
			if(forceFire){
			//ObservableUtils.forceFirePropertyChanged(this, "espaciosLibresAcuatico", this.getEspaciosLibresAcuatico());
			}
		}
	}

	
	/**
	 * Metodo generico para agregar planta, trabaja sobre un array.
	 * @param planta
	 * @param jardin
	 * @param maximo
	 */
	public void agregarPlantaAJardin(Planta planta, ArrayList<Planta>jardin, int maximo){
		if (!this.jardinLleno(jardin, maximo)) {
			jardin.add(planta);
			
		}else{
			throw new JardinZenLleno();
		}
	}
	

	/**
	 * Metodo generico para verificar un jardin lleno, compara tamano
	 * del array parametro contra el tamano maximo provisto.
	 * @param ArrayList<Planta>
	 * @param maximo
	 * @return
	 */
	public boolean jardinLleno(ArrayList<Planta> jardin , int maximo){
		return jardin.size() == maximo;
	}
	
	public void mejorarPlanta(Planta p, int ataque, int defensa){
		this.getPlanta(p.getNombre()).aumentarAtaqueYDefensa(ataque, defensa);
	}

	/**
	 * Se obtiene una planta determinada tanto acuatica o terrestrepor su
	 * nombre, se asume que cada plantin es unico en su nombre
	 * 
	 * @param String nombre
	 * @return Planta
	 */
	public Planta getPlanta(String nombre) {
		for (Planta p : this.jardinAcuatico) {
			if (p.getNombre().equals(nombre)) {
				return p;
			}
		}
		for (Planta p : this.jardinTerrestre) {
			if (p.getNombre().equals(nombre)) {
				return p;
			}
		}
		return null;
	}
	
	public void reiniciar() {
		this.setJardinAcuatico(new ArrayList<Planta>());
		this.setJardinTerrestre(new ArrayList<Planta>());
	}
	
	public int getEspaciosLibresTerrestre() {
		return this.sizeTerrestre - this.jardinTerrestre.size();
	}
	
	public int getEspaciosLibresAcuatico() {
		return this.sizeAcuatico - this.jardinAcuatico.size();
	}
	
	public int getSizeTerrestre() {
		return sizeTerrestre;
	}

	public void setSizeTerrestre(int sizeTerrestre) {
		this.sizeTerrestre = sizeTerrestre;
	}

	public int getSizeAcuatico() {
		return sizeAcuatico;
	}

	public void setSizeAcuatico(int sizeAcuatico) {
		this.sizeAcuatico = sizeAcuatico;
	}

	public ArrayList<Planta> getJardinAcuatico() {
		return jardinAcuatico;
	}

	public void setJardinAcuatico(ArrayList<Planta> jardinAc) {
		jardinAcuatico = jardinAc;
	}

	public ArrayList<Planta> getJardinTerrestre() {
		return jardinTerrestre;
	}

	public void setJardinTerrestre(ArrayList<Planta> jardinTer) {
		jardinTerrestre = jardinTer;
	}

	public Planta getPlantinAMejorar() {
		return plantinAMejorar;
	}

	public void setPlantinAMejorar(Planta plantinAMejorar) {
		this.plantinAMejorar = plantinAMejorar;
	}
}
